package com.zhenwei.zscm.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhenwei.zscm.common.exception.CustomException;
import com.zhenwei.zscm.common.base.RestMsg;
import com.zhenwei.zscm.common.base.RestResult;
import com.zhenwei.zscm.common.base.UserContext;
import com.zhenwei.zscm.common.utils.Linq;
import com.zhenwei.zscm.model.dto.menu.MenuDTO;
import com.zhenwei.zscm.model.dto.roleAuth.RoleAuthDTO;
import com.zhenwei.zscm.model.dto.user.UserDTO;
import com.zhenwei.zscm.model.enums.RoleEnum;
import com.zhenwei.zscm.model.vo.roleAuth.RoleAuthVO;
import com.zhenwei.zscm.repo.DictRepo;
import com.zhenwei.zscm.repo.LogRepo;
import com.zhenwei.zscm.repo.MenuRepo;
import com.zhenwei.zscm.repo.RoleAuthRepo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class RoleAuthService {
    private final DictRepo dictRepo;
    private RoleAuthRepo roleAuthRepo;
    private MenuRepo menuRepo;
    private LogRepo logRepo;
    private final String LOG_TYPE = "角色权限设置";

    public RestResult getRoleAuth(String role) {
        RoleAuthDTO roleAuth = roleAuthRepo.getRoleAuth(role);
        return RestResult.success(roleAuth, 0);
    }

    public RestResult createRoleAuth(RoleAuthDTO roleAuthDTO){
        // 系统默认角色权限不能添加
        if(RoleEnum.ADMIN.name().equals(roleAuthDTO.getRole()) || RoleEnum.USER.name().equals(roleAuthDTO.getRole())){
            return RestResult.fail(RestMsg.CAN_NOT_CREATE_ADMIN_ROLE);
        }
        // 检查是否添加过
        RoleAuthDTO roleAuth = roleAuthRepo.getRoleAuth(roleAuthDTO.getRole());
        if(roleAuth != null){
            return RestResult.fail(RestMsg.ROLE_AUTH_EXISTS);
        }
        //
        boolean created = roleAuthRepo.createRoleAuth(roleAuthDTO);
        if(created){
            logRepo.createAsync(LOG_TYPE, "添加角色权限->"+roleAuthDTO);
        }
        return RestResult.r(created);
    }

    public RestResult updateRoleAuth(RoleAuthDTO dto){
        // 系统默认角色权限不能添加
        if(RoleEnum.ADMIN.name().equals(dto.getRole())){
            return RestResult.fail(RestMsg.CAN_NOT_UPDATE_ADMIN_ROLE);
        }
        // 检查是否添加过
        RoleAuthDTO roleAuth = roleAuthRepo.getRoleAuth(dto.getRole());
        if(roleAuth == null){
            return RestResult.fail(RestMsg.ROLE_AUTH_NOT_EXISTS);
        }
        boolean deleted = roleAuthRepo.deleteRoleAuth(dto.getRole());
        if(!deleted){
            return RestResult.fail(RestMsg.FAILURE);
        }
        boolean created = roleAuthRepo.createRoleAuth(dto);
        if(created){
            logRepo.createAsync(LOG_TYPE, "修改角色权限->"+dto);
        }
        return RestResult.r(created);
    }

    public RestResult list() {
        var list = roleAuthRepo.all();
        return RestResult.success(list, list.size());
    }

    public RestResult updateMenuAuth(RoleAuthVO vo) {
        if(vo.getMenus() == null || vo.getMenus().isEmpty()){
            vo.setMenus(new ArrayList<>());
        }
        try {
            var updated = roleAuthRepo.updateMenuAuth(vo.getRole(), vo.getRoleName(), vo.getMenus());
            if (updated) {
                logRepo.createAsync(LOG_TYPE, "修改角色菜单权限->"+vo);
            }
            return RestResult.r(updated);
        } catch (JsonProcessingException e) {
            throw new CustomException(RestMsg.FAILURE);
        }
    }

    public RestResult updateApiAuth(RoleAuthVO vo) {
        if(vo.getApis() == null || vo.getApis().isEmpty()){
            vo.setApis(new ArrayList<>());
        }
        try {
            var updated = roleAuthRepo.updateApiAuth(vo.getRole(), vo.getRoleName(), vo.getApis());
            if (updated) {
                logRepo.createAsync(LOG_TYPE, "修改角色接口权限->"+vo);
            }
            return RestResult.r(updated);
        } catch (JsonProcessingException e) {
            throw new CustomException(RestMsg.FAILURE);
        }
    }

    public RestResult checkMenuAuth(String menuCode) {
        UserDTO currentUser = UserContext.getCurrentUser();
        RoleAuthDTO roleAuth = roleAuthRepo.getRoleAuth(currentUser.getRole());
        List<MenuDTO> authMenu = roleAuth.getAuthMenu();
        boolean exists = Linq.exists(authMenu, x -> x.getMenuCode().equals(menuCode));
        return RestResult.success(exists, 0);
    }
}
